#include <SIMULATE_SIGNAL_module/SIMULATE_SIGNAL.hpp>

#ifdef DBG_TAG
#undef DBG_TAG
#endif
#ifdef DBG_LVL
#undef DBG_LVL
#endif

#define DBG_TAG     "simu_signal"
#define DBG_LVL     DBG_LOG

extern "C"
{
#include <rtdbg.h>
}

using namespace std;

/******************************************************************************
 *
 * @brief:     SIMULATE_SIGNAL类实现
 *
 ******************************************************************************/
SIMULATE_SIGNAL::SIMULATE_SIGNAL(CHIP_OUTPUT_PIN *A_pin,
                                 CHIP_OUTPUT_PIN *B_pin,
                                 uint32_t min_cycle_time)
{
    if (!A_pin || !B_pin)
    {
        LOG_E("input pin A or B is NULL");
        goto end;
    }

    this->A_pin = A_pin;
    this->B_pin = B_pin;
    this->min_cycle_time = min_cycle_time;
    this->last_times = 0;
    this->debug_flag = 0;

    if (A_pin->CHIP_OUTPUT_read_init_status() != chip_pin_status_ok
            || B_pin->CHIP_OUTPUT_read_init_status() != chip_pin_status_ok)
    {
        LOG_E("input pin A or B is not init ok");
        goto end;
    }

    data_sem =rt_sem_create("sig_sem", 0, RT_IPC_FLAG_FIFO);
    if (!data_sem)
    {
        LOG_E("sig_sem is not init ok");
        goto end;
    }


    data_lock =rt_mutex_create("sig_lock", RT_WAITING_FOREVER);
    if (!data_lock)
    {
        LOG_E("sig_lock is not init ok");
        goto end;
    }

    A_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_LOW);
    B_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_LOW);
    LOG_I("simulate signal create ok");
    init_flag = simulate_signal_status_ok;
    return;
    end:
    LOG_E("simulate signal create fail");
    init_flag = simulate_signal_status_fail;
}

void SIMULATE_SIGNAL::SIMULATE_SIGNAL_in_thread_function()
{
   uint32_t cycle_time_ms;
    if (init_flag != simulate_signal_status_ok) while (1)
    {
        LOG_E("simulate signal not init ok,pls contact tech");
        rt_thread_mdelay(1000);
    }
    uint32_t _1_of_4_min_cycle_time_us = min_cycle_time / 4;
    uint32_t _1_of_4_cycle_time_ms ;

    cycle_time_ms = 100;

    while (1)
    {
        rt_sem_take(data_sem, RT_WAITING_FOREVER);
        rt_mutex_take(data_lock, RT_WAITING_FOREVER);
        while(last_times)
        {
            cycle_time_ms = 200 /last_times;
            _1_of_4_cycle_time_ms = cycle_time_ms / 4;
            if(_1_of_4_cycle_time_ms < 10)
            {
                A_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_HIGH);
                B_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_LOW);

                rt_hw_us_delay(_1_of_4_min_cycle_time_us);
                B_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_HIGH);
                rt_hw_us_delay(_1_of_4_min_cycle_time_us);
                A_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_LOW);
                rt_hw_us_delay(_1_of_4_min_cycle_time_us);
                B_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_LOW);
                rt_hw_us_delay(_1_of_4_min_cycle_time_us);

            }
            else
            {
                A_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_HIGH);
                B_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_LOW);

                rt_thread_mdelay(_1_of_4_cycle_time_ms);
                B_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_HIGH);
                rt_thread_mdelay(_1_of_4_cycle_time_ms);
                A_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_LOW);
                rt_thread_mdelay(_1_of_4_cycle_time_ms);
                B_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_LOW);
                rt_thread_mdelay(_1_of_4_cycle_time_ms);
            }
            last_times--;

        }
        rt_mutex_release(data_lock);

    }

}

void SIMULATE_SIGNAL::SIMULATE_SIGNAL_add_signal(uint32_t signal_time)
{
    if (init_flag != simulate_signal_status_ok) return;
    if(signal_time > 0)
    {
        rt_mutex_take(data_lock, RT_WAITING_FOREVER);
    //    if(debug_flag)
    //        LOG_D("now wave time <%u> add num <%u>",last_times,signal_time);
        last_times+=signal_time;
        rt_mutex_release(data_lock);
        rt_sem_release(data_sem);
    }
}

void SIMULATE_SIGNAL::SIMULATE_SIGNAL_open_debug()
{
    debug_flag =1 ;
}
